<template>
  <el-button circle plain type="primary" style="margin-bottom: 4px"
             @click="addField" title="增加字段">
    <el-icon>
      <Plus/>
    </el-icon>
  </el-button>
  <el-table :data="paramDesc.fields" border>
    <el-table-column type="index" label="序号" :width="tbCols.index"/>

    <el-table-column label="排序" :width="tbCols.orderNo">
      <template #default="scope">
        <el-input type="number" :min="0" :max="300" v-model="scope.row.orderNo"
                  @change="sortFields(scope.row)" size="small"/>
      </template>
    </el-table-column>

    <el-table-column prop="fieldName" label="字段名称" :width="tbCols.fieldName"/>
    <el-table-column label="字段类型" :width="tbCols.fieldType">
      <template #default="scope">
        {{ getFieldTypeName(scope.row) }}
      </template>
    </el-table-column>

    <el-table-column label="是否必填" :width="tbCols.fieldMust">
      <template #default="scope">
        <el-radio-group v-model="scope.row.fieldMust" size="small">
          <el-radio-button label="是">是</el-radio-button>
          <el-radio-button label="否">否</el-radio-button>
        </el-radio-group>
      </template>
    </el-table-column>

    <el-table-column label="描述模式" :width="tbCols.descMode">
      <template #default="scope">
        <el-select v-model="scope.row.descMode" size="small">
          <el-option v-for="item in descModes" :key="item.enumValue" :value="item.enumValue"
                     :label="item.enumName" :title="item.enumDesc"/>
        </el-select>
      </template>
    </el-table-column>

    <el-table-column label="字段所属" :width="tbCols.fieldType">
      <template #default="scope">
        <el-select v-model="scope.row.apiId" size="small" @change="findUniKey(scope.row)">
          <el-option v-for="item in fieldApiType" :key="item.value" :value="item.value"
                     :label="item.label" :title="item.title"/>
        </el-select>
      </template>
    </el-table-column>

    <el-table-column prop="fieldDescOut" label="字段描述" :show-overflow-tooltip="true" :width="tbCols.fieldDesc"/>
    <el-table-column label="操作" :width="tbCols.open">
      <template #default="scope">
        <el-button text type="primary" @click="updateOne(scope.row)" title="修改更多字段" class="icon-button">
          <el-icon>
            <Edit/>
          </el-icon>
        </el-button>
        <el-button text type="warning" title="删除该字段" class="icon-button"
                   @click="deleteOneField(scope.row)" style="margin-left: 0">
          <el-icon>
            <Delete/>
          </el-icon>
        </el-button>
      </template>
    </el-table-column>
  </el-table>

  <!-- GPT生成 -->
  <el-dialog :title="dialogTitle" v-model="updateFieldFlag" width="800px" draggable>
    <!-- 增加已有字段 -->
    <el-row align="middle" style="margin-bottom: 12px">
      <el-col :span="4" :offset="6">
        选择已存在字段
      </el-col>
      <el-col :span="7">
        <el-select style="width: 260px" v-model="selectField" filterable remote value-key="id" clearable
                   reserve-keyword placeholder="请输入字段名称" :remote-method="findFields"
                   :loading="loading" @change="selectFieldChange">
          <el-option v-for="item in optionFields"
                     :key="item.id" :label="item.fieldName +getFieldDesc(item)" :value="item">
          </el-option>
        </el-select>
      </el-col>
    </el-row>

    <!--  修改内容  -->
    <el-form ref="form" :model="form" :rules="rules" label-width="120px" class="param-form">
      <el-form-item label="字段名称" prop="fieldName">
        <el-input v-model="form.fieldName" placeholder="请输入字段名称" @change="findUniKey(form)"/>
      </el-form-item>

      <el-form-item label="字段类型" prop="fieldTypeId">
        <el-select v-model="form.fieldTypeId" placeholder="请选择字段类型" @change="findUniKey(form)">
          <el-option v-for="type in fieldTypes" :key="type.enumValue" :label="type.enumName"
                     :title="type.enumDesc" :value="type.enumValue"></el-option>
        </el-select>
      </el-form-item>

      <el-form-item label="字段所属" prop="apiId">
        <el-select v-model="form.apiId" @change="findUniKey(form)">
          <el-option v-for="item in fieldApiType" :key="item.value" :value="item.value"
                     :label="item.label" :title="item.title"/>
        </el-select>
      </el-form-item>

      <el-form-item label="是否必填" prop="fieldMust">
        <el-radio-group v-model="form.fieldMust" size="small">
          <el-radio-button label="是">是</el-radio-button>
          <el-radio-button label="否">否</el-radio-button>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="通用描述" prop="fieldDesc">
        <el-input type="textarea" v-model="form.fieldDesc" @change="descOutChange"
                  title="字段通用描述，与其它接口、参数公用"/>
      </el-form-item>
      <el-form-item label="参数描述" prop="paramFieldDesc">
        <el-input type="textarea" v-model="form.paramFieldDesc" @change="descOutChange"
                  title="该参数字段描述，在该参数中特有"/>
      </el-form-item>

      <el-form-item label="描述模式" prop="descMode">
        <el-select v-model="form.descMode" size="small" @change="descOutChange">
          <el-option v-for="item in descModes" :key="item.enumValue" :value="item.enumValue"
                     :label="item.enumName" :title="item.enumDesc"/>
        </el-select>
      </el-form-item>

      <el-form-item label="描述预览" prop="fieldDescOut">
        <pre><span title="根据描述模式、通用描述、参数描述生成">{{ form.fieldDescOut }}</span></pre>
      </el-form-item>

    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="addOneFieldDo"
                 title="确定并不会生效，需要在修改页面保存才会生效">确 定
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import {Plus, Edit, Delete} from '@element-plus/icons-vue'
import ApiUtil from "@/utils/api-utils/ApiUtil";
import CommonUtils from "@/utils/CommonUtils";
import ApiDocConstants from "@/utils/api-utils/ApiDocConstants";
import {ElMessage} from "element-plus";
import myaxios from "@/plugins/myaxios";
import FormRules from "@/utils/FormRules";

export default {
  name: "FieldUpdate",
  components: {
    Plus, Edit, Delete
  },
  props: {
    paramDesc: Object
  },
  data() {
    return {
      tbCols: {
        index: 55,
        orderNo: 80,
        fieldName: 155,
        fieldType: 90,
        fieldMust: 100,
        fieldDesc: 300,
        descMode: 100,
        open: 80
      },
      form: ApiDocConstants.getFieldDemo(),
      selectField: ApiDocConstants.getFieldDemo(),
      updateFieldFlag: false,
      rules: {
        fieldName: FormRules.rules.fieldName,
        fieldTypeId: FormRules.rules.fieldType,
        fieldMust: FormRules.rules.must,
        fieldDesc: FormRules.rules.fieldCommon,
        enableFlag: FormRules.rules.enableFlag
      },
      fieldTypes: this.$store.state.allEnum.fieldType,
      fieldTypeMap: {},
      descModes: [],
      fieldApiType: [{
        value: 1,
        label: '通用字段',
        title: '多个接口使用同一个字段，共用公共字段说明'
      }],
      addFlag: false,
      dialogTitle: '修改字段',
      loading: false,
      optionFields: [ApiDocConstants.getFieldDemo()]
    }
  },
  methods: {
    setFieldTypes() {
      this.fieldTypes = this.$store.state.allEnum.fieldType
      this.fieldTypeMap = this.$store.state.allEnum.fieldTypeMap
      this.descModes = this.$store.state.allEnum.descMode
      if (this.paramDesc.apiId) {
        this.fieldApiType.unshift({
          value: this.paramDesc.apiId,
          label: '本接口字段',
          title: '同一个接口公用一个字段，共用公共字段说明'
        })
      }
    },
    getFieldTypeName(field) {
      if (this.fieldTypeMap === {}) {
        this.setFieldTypes()
      }
      if (field.fieldTypeId || field.fieldTypeId === 0) {
        return this.fieldTypeMap[field.fieldTypeId.toString()]
      } else {
        return '无数据'
      }
    },
    sortFields(field) {
      ApiUtil.sortByOrderNo(this.paramDesc.fields, field)
    },
    deleteOneField(field) {
      this.$confirm("确定要删除： " + field.fieldName + ' 字段吗？', '确认删除', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(() => {
        this.paramDesc.fields.splice(this.paramDesc.fields.indexOf(field), 1)
      })
    },
    updateOne(field) {
      this.form = field
      this.updateFieldFlag = true
      this.addFlag = false
      this.dialogTitle = '修改字段'
    },
    descOutChange() {
      switch (this.form.descMode) {
        case 0:
          this.form.fieldDescOut = this.form.fieldDesc + this.form.paramFieldDesc
          break
        case 1:
          this.form.fieldDescOut = this.form.paramFieldDesc + this.form.fieldDesc
          break
        case 2:
          this.form.fieldDescOut = this.form.paramFieldDesc
          break
        default:
          this.form.fieldDescOut = this.form.fieldDesc
      }
    },
    addField() {
      this.updateFieldFlag = true
      this.addFlag = true
      this.dialogTitle = '增加字段'

      this.form = CommonUtils.cloneObj(ApiDocConstants.getFieldDemo())
      this.form.apiId = this.paramDesc.apiId
      this.form.paramId = this.paramDesc.id
    },
    // 增加新字段
    addOneFieldDo() {
      this.$refs.form.validate(valid => {
        if (valid) {
          this.form.fieldName = this.form.fieldName.trim()
          let order = 1
          for (const fieldOne of this.paramDesc.fields) {
            fieldOne.orderNo = (order++)
            if (this.addFlag && this.form.fieldName === fieldOne.fieldName) {
              ElMessage.error('字段名称已存在,不能重复新增.')
              return
            }
          }
          this.descOutChange()

          // 增加字段
          if (this.addFlag) {
            this.form.orderNo = this.paramDesc.fields.length + 1
            this.paramDesc.fields.splice(this.form.orderNo, 0, this.form)
          }
          this.updateFieldFlag = false
        }
      })
    },
    findFields(query) {
      if (query !== '') {
        this.loading = true
        setTimeout(() => {
          myaxios.get("/dist/field/like", {
            params: {
              world: query,
              apiId: this.paramDesc.apiId,
              spaceId: this.$store.state.space.id
            }
          }).then(rep => {
            if (rep.data.code !== 100) {
              ElMessage.error(rep.data.msg)
            } else {
              this.optionFields = rep.data.data
            }
            this.loading = false;
          }, err => {
            ElMessage.error(err.response.data)
          })
        }, 200);
      } else {
        this.optionFields = ApiDocConstants.documentsInfo.currentApiInfo.apiParamDescVo.inputHeader.fields;
      }
    },
    // 获取字段类型
    getFieldDesc(field) {
      const fieldType = this.fieldTypeMap[field.fieldTypeId?.toString()] ?? 'OTHER';
      const fieldApiType = this.fieldApiType.find(type => type.value === field.apiId);
      const fieldTypeStr = fieldApiType?.label ?? '其它接口字段';
      return `(${fieldType}-${fieldTypeStr})`;
    },
    findUniKey(field) {
      if (!field.apiId && !field.fieldName && !field.fieldTypeId && !field.spaceId) {
        return
      }
      myaxios.post("/dist/field/uniKey", field).then(rep => {
        if (rep.data.code !== 100) {
          ElMessage.error(rep.data.msg)
        } else {
          let fieldDb = rep.data.data
          if (fieldDb) {
            field.id = fieldDb.id
            field.fieldDesc = fieldDb.fieldDesc
          }
        }
        this.loading = false;
      }, err => {
        ElMessage.error(err.response.data)
      })
    },
    selectFieldChange () {
      console.log(this.selectField)
      this.form.id = this.selectField.id;
      this.form.fieldName = this.selectField.fieldName;
      this.form.fieldTypeId = this.selectField.fieldTypeId;
      this.form.apiId = this.selectField.apiId;
      this.form.fieldDesc = this.selectField.fieldDesc;
      this.form.usePriority = this.selectField.usePriority;
      this.form.creator = this.selectField.creator;
      this.form.createTime = this.selectField.createTime;
      this.form.enableFlag = this.selectField.enableFlag;
    }
  },
  mounted() {
    this.setFieldTypes()
  }
}
</script>

<style scoped>

.icon-button {
  margin: 0;
  padding: 6px;
}

pre {
  margin: 0;
  background-color: #EFEFEF;
  text-align: left;
  line-height: 1.2;
}
</style>